// Copyright 2008 Senary
// See credits.txt for details.

// This file is part of Omega VII.

// Omega VII is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// Omega VII is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with Omega VII.  If not, see <http://www.gnu.org/licenses/>.

#pragma once

#include <utility>

#include "Vector.h"
#include "Angle.h"
#include "Constants.h"

class ImagePanel;

// maximal rotation speed of a ship
const double SHIP_ROTATION_SPEED = M_PI / 3.0; // needs six seconds for a full turn

// default orbiting time of a ship
const double SHIP_ORBITING_TIME = 10.0;

class Player;

class SpaceObject
{
protected:
	Vector _position;
	Vector _angle;
	Vector _velocity;

	Player* _owner;

	// The object around which this object orbits
	SpaceObject* _orbitalTarget;

	// The two vectors define the two half axes of the elliptical orbit.
	std::pair<Vector, Vector> _orbitalEllipse;

	// The duration of one period (i.e. time needed for one orbit)
	float _orbitalTime;
	
	// The time when the orbit started (the phase, so to speak...)
	float _orbitalStartTime;

	// Decoration Panel for the spaceObject
	ImagePanel* _imagePanel;


public:
	SpaceObject(void);
	virtual ~SpaceObject(void);
	//get/set
	Vector getPosition(void) const;
	Vector getAngle(void) const;
	Vector getVelocity(void) const;
	Player * getOwner() const;
	void setPosition(Vector const& position);
	void setAngle(Vector const& angle);
	void setVelocity(Vector const& velocity);
	virtual void setOwner(Player * owner);

	SpaceObject* getOrbitalTarget(void);
	virtual void setOrbitalTarget(SpaceObject* target);

	std::pair<Vector, Vector> getOrbitalEllipse(void);
	void setOrbitalEllipse(std::pair<Vector, Vector> const& ellipse);

	float getOrbitalTime(void);
	void setOrbitalTime(float orbitalTime);
	float getOrbitalStartTime(void);
	void setOrbitalStartTime(float orbitalStartTime);

	// Getter for the image panel
	// Needed because it's updated through UnitDecorator
	ImagePanel* getDecorationPanel();

	// starts orbiting around a planet... use this as an intelligent
	// shortcut for the setOrbital* functions
	// param totalTime: the current game time (to avoid jumps)
	void startOrbit(SpaceObject* target, float totalTime);

	// Updates position, velocity etc. of the space object
	// param timestep: time since the last update, in seconds
	// param totalTime: total time the game has been running
	virtual void update(float timestep, float totalTime);

	// Checks if two spaceObjects are "close" to each other. 
	// The meaning depends on the type, whether they're
	// ennemies and so on.
	virtual bool isInRange(SpaceObject const& other) const = 0;

	// This method is called when a spaceship died, so others can react
	virtual void somebodyDied(SpaceObject const* who);

	void reactToCollision(void);
};
